Passed
Push — development ( e131c7...d0a4d7 )
by Peter
05:27 queued 13s
created

UsersController.getCustomerById   A

Complexity

Conditions 1

Size

Total Lines 38
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.125

Importance

Changes 0
Metric Value
cc 1
eloc 31
dl 0
loc 38
ccs 1
cts 2
cp 0.5
crap 1.125
rs 9.1359
c 0
b 0
f 0
1 1
import { BadRequestException, Controller, Param, ForbiddenException } from '@nestjs/common';
2 1
import { UsersService } from './users.service';
3 1
import { Patch, Get, Body, Req, Post, UseGuards, Request } from '@nestjs/common';
0 ignored issues
show
introduced by
'@nestjs/common' import is duplicated.
Loading history...
4 1
import { UpdateTermsDto } from './dto/update-terms.dto/update-terms.dto';
5 1
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
6 1
import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiResponse } from '@nestjs/swagger';
7 1
import { UpdateUserDto } from './dto/update-user.dto/update-user.dto';
8 1
import { AdjustFundsDto } from './dto/update-user.dto/adjust-funds.dto';
9 1
import { AdminGuard } from '../auth/guards/admin.guard';
10
11
@Controller('users')
12 1
export class UsersController {
13 7
  constructor(private readonly usersService: UsersService) {}
14
15
  @Patch('terms')
16
  @UseGuards(JwtAuthGuard)
17
  @ApiBearerAuth()
18
  @ApiOperation({ summary: 'Update terms acceptance status' })
19
  @ApiBody({
20
    description: 'The body containing the updated terms acceptance status',
21
    type: UpdateTermsDto,
22
  })
23
  @ApiResponse({
24
    status: 200,
25
    description: 'Terms acceptance status updated successfully',
26
    examples: {
27
      'application/json': {
28
        summary: 'Example of a successful terms update',
29
        value: {
30
          githubId: '12345',
31
          hasAcceptedTerms: true,
32
        },
33
      },
34
    },
35
  })
36
  @ApiResponse({
37
    status: 400,
38
    description: 'Invalid input',
39
  })
40
  @ApiResponse({
41
    status: 401,
42
    description: 'Unauthorized. Authentication required',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 4 times.
Loading history...
43
  })
44 1
  async updateTerms(@Req() req, @Body() updateTermsDto: UpdateTermsDto) {
45 6
    if (typeof updateTermsDto.hasAcceptedTerms !== 'boolean') {
46 2
      throw new BadRequestException('Invalid input');
47
    }
48
    // console.log(req.user);
49 4
    return await this.usersService.updateTerms(req.user.githubId, updateTermsDto.hasAcceptedTerms);
50
  }
51
  // Fetch all customers
52
  @Get()
53
  @UseGuards(JwtAuthGuard, AdminGuard)
54
  @ApiBearerAuth()
55
  @ApiOperation({ summary: 'Get all customers (Only for admin)' })
56
  @ApiResponse({
57
    status: 200,
58
    description: 'List of customers',
59
    examples: {
60
      'application/json': {
61
        summary: 'Example of a list of customers',
62
        value: [
63
          {
64
            githubId: '169550',
65
            username: 'three-musketeers',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 3 times.
Loading history...
66
            email: 'dasthreemusketö[email protected]',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 3 times.
Loading history...
67
            roles: ['user'],
68
            hasAcceptedTerms: false,
69
            avatarUrl: 'https://avatars.githubusercontent.com/u/169550?v=4',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 3 times.
Loading history...
70
            createdAt: '2024-12-01T05:01:01.000Z',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 3 times.
Loading history...
71
            updatedAt: '2024-12-07T18:30:30.000Z',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 3 times.
Loading history...
72
          },
73
          {
74
            githubId: '169550',
75
            username: 'three-musketeers',
76
            email: 'dasthreemusketö[email protected]',
77
            roles: ['user'],
78
            hasAcceptedTerms: false,
79
            avatarUrl: 'https://avatars.githubusercontent.com/u/169550?v=4',
80
            createdAt: '2024-12-01T05:01:01.000Z',
81
            updatedAt: '2024-12-07T18:30:30.000Z',
82
          },
83
        ],
84
      },
85
    },
86
  })
87
  @ApiResponse({
88
    status: 401,
89
    description: 'Unauthorized. Authentication required',
90
  })
91
  @ApiResponse({
92
    status: 403,
93
    description: 'Forbidden. Admin access required',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 3 times.
Loading history...
94
  })
95 1
  async getAllCustomers() {
96
    // return {userid: "hej1"};
97
    return await this.usersService.findAll();
98
  }
99
  // Fetch a customer by ID
100
  @Get(':githubId')
101
  @UseGuards(JwtAuthGuard, AdminGuard)
102
  @ApiBearerAuth()
103
  @ApiOperation({ summary: 'Get customer by id (Only for admin)' })
104
  @ApiResponse({
105
    status: 200,
106
    description: 'Customer details returned by id',
107
    examples: {
108
      'application/json': {
109
        summary: 'Example of a customer',
110
        value: {
111
          githubId: '169550',
112
          username: 'three-musketeers',
113
          email: 'dasthreemusketö[email protected]',
114
          roles: ['user'],
115
          hasAcceptedTerms: false,
116
          avatarUrl: 'https://avatars.githubusercontent.com/u/169550?v=4',
117
          createdAt: '2024-12-01T05:01:01.000Z',
118
          updatedAt: '2024-12-07T18:30:30.000Z',
119
        },
120
      },
121
    },
122
  })
123
  @ApiResponse({
124
    status: 404,
125
    description: 'Customer not found',
126
  })
127
  @ApiResponse({
128
    status: 401,
129
    description: 'Unauthorized. Authentication required',
130
  })
131
  @ApiResponse({
132
    status: 403,
133
    description: 'Forbidden. Admin access required',
134
  })
135 1
  async getCustomerById(@Param('githubId') githubId: string) {
136
    return await this.usersService.findById(githubId);
137
  }
138
  // Update a customer by ID
139
  @Patch(':githubId')
140
  @UseGuards(JwtAuthGuard, AdminGuard)
141
  @ApiBearerAuth()
142
  @ApiOperation({ summary: 'Update customer by githubId (Only for admin)' })
143
  @ApiParam({
144
    name: 'githubId',
145
    description: 'The GitHub ID of the user',
146
    example: '12345',
147
  })
148
  @ApiBody({
149
    description: 'The body containing the updated user details',
150
    type: UpdateUserDto,
151
  })
152
  @ApiResponse({
153
    status: 200,
154
    description: 'Customer updated successfully',
155
    examples: {
156
      'application/json': {
157
        summary: 'Example of a successful customer update',
158
        value: {
159
          githubId: '12345',
160
          email: '[email protected]',
161
          roles: ['admin'],
162
          hasAcceptedTerms: true,
163
        },
164
      },
165
    },
166
  })
167
  @ApiResponse({
168
    status: 400,
169
    description: 'Invalid input with error message',
170
  })
171
  @ApiResponse({
172
    status: 404,
173
    description: 'Customer not found',
174
  })
175
  @ApiResponse({
176
    status: 401,
177
    description: 'Unauthorized. Authentication required',
178
  })
179
  @ApiResponse({
180
    status: 403,
181
    description: 'Forbidden. Admin access required',
182
  })
183 1
  async updateCustomer(@Param('githubId') githubId: string, @Body() updateUserDto: UpdateUserDto) {
184
    return this.usersService.update(githubId, updateUserDto);
185
  }
186
187
  @Get(':githubId/account')
188
  @UseGuards(JwtAuthGuard)
189
  @ApiBearerAuth()
190
  @ApiOperation({
191
    summary: 'Get account balance and accumulated cost',
192
    description: 'Returns the users balance and accumulated monthly payment cost.',
193
  })
194
  @ApiResponse({
195
    status: 200,
196
    description: 'Account details retrieved successfully.',
197
  })
198 1
  async getAccountDetails(@Param('githubId') githubId: string) {
199
    const user = await this.usersService.findById(githubId);
200
    return {
201
      balance: user.balance,
202
      accumulatedCost: user.accumulatedCost,
203
      isMonthlyPayment: user.isMonthlyPayment,
204
    };
205
  }
206
  @Post(':githubId/adjust-funds')
207
  @UseGuards(JwtAuthGuard)
208
  @ApiBearerAuth()
209
  @ApiOperation({
210
    summary: 'Adjust user balance and payment mode',
211
    description: 'Set a new balance for the user and optionally toggle monthly payment mode.',
212
  })
213
  @ApiResponse({
214
    status: 200,
215
    description: 'User balance adjusted successfully',
216
  })
217
  @ApiResponse({
218
    status: 404,
219
    description: 'User not found',
220
  })
221
  @ApiResponse({
222
    status: 403,
223
    description: 'Forbidden. You cannot adjust other users unless you are an admin.',
224
  })
225 1
  async adjustFunds(
226
    @Param('githubId') githubId: string,
227
    @Body() adjustFundsDto: AdjustFundsDto,
228
    @Request() req: any,
229
  ) {
230
    const authenticatedUser = req.user;
231
232
    // Only allow if the user is an admin or adjusting their own account
233 3
    if (authenticatedUser.githubId !== githubId && !authenticatedUser.roles.includes('admin')) {
234
      throw new ForbiddenException("You are not allowed to adjust other users' accounts.");
235
    }
236
237
    return await this.usersService.adjustFunds(githubId, adjustFundsDto);
238
  }
239
}
240